package com.differ.log.core;

import java.lang.reflect.Method;

import javax.annotation.Resource;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.differ.log.core.dto.LogBean;
import com.differ.log.enums.OperateType;
import com.differ.log.utils.ReflectionUtils;

import tk.mybatis.mapper.common.BaseMapper;

@Aspect
@Order(-99)
@Component
public class LogAspect {
	private Logger logger = LoggerFactory.getLogger(getClass().getName());

	@Resource
	private DiffUtils diffUtils;
	@Pointcut("execution(public * com.differ.log.tk.BaseMapper." + TkMyBatisAPI.insertUseGeneratedKeys + "(..))")
	public void insert() {
	}

	@Pointcut("execution(public * com.differ.log.tk.BaseMapper." + TkMyBatisAPI.updateByPrimaryKeySelective + "(..))")
	public void update() {
	}

	@Pointcut("execution(public * com.differ.log.tk.BaseMapper." + TkMyBatisAPI.deleteByPrimaryKey + "(..))")
	public void delete() {
	}

	@Around("insert() || update() || delete()")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		Object[] args = pjp.getArgs();
		System.out.println("-------" + pjp.getTarget().getClass());
		Signature s = pjp.getSignature();
		MethodSignature ms = (MethodSignature) s;
		Method m = ms.getMethod();
		System.out.println("当前方法:" + m.getName());
		Object working = null;
		if (args.length == 1) {
			working = args[0];
			LogBean logBean=null;
			switch (m.getName()) {
			case TkMyBatisAPI.updateByPrimaryKeySelective:
				Object id = ReflectionUtils.getProperty(working, "id");
				System.out.println("ID===" + id);
				if(id!=null) {
					BaseMapper<?> mapper = (BaseMapper<?>) pjp.getTarget();
					Object base = mapper.selectByPrimaryKey(id);
					if (base != null) {
						logger.info("旧对象：" + JSONObject.toJSONString(base, true));
						logger.info("新对象：" + JSONObject.toJSONString(working, true));
						logBean = diffUtils.exctor(id,base, working, working.getClass(), OperateType.UPDATE);
						logger.info("变化：" + JSONObject.toJSONString(logBean, true));
					}
				}
				break;
			case TkMyBatisAPI.deleteByPrimaryKey:
				Object idVlue = args[0];
				System.out.println("ID===" + idVlue);
				if(idVlue!=null) {
					BaseMapper<?> mapper = (BaseMapper<?>) pjp.getTarget();
					Object base = mapper.selectByPrimaryKey(idVlue);
					if (base != null) {
						logger.info("旧对象：" + JSONObject.toJSONString(base, true));
						logger.info("新对象：" + null);
						logBean = diffUtils.exctor(idVlue,base, null, base.getClass(), OperateType.DELEET);
						logger.info("变化：" + JSONObject.toJSONString(logBean, true));
					}
				}
				break;
			default:
				break;
			}

		}
		Object result = pjp.proceed();
		if(args.length == 1&&TkMyBatisAPI.insertUseGeneratedKeys.equals(m.getName())) {
			Object id = ReflectionUtils.getProperty(working, "id");
			System.out.println(id);
			LogBean logBean = diffUtils.exctor(id,null, working, working.getClass(), OperateType.ADD);
			logger.info("变化：" + JSONObject.toJSONString(logBean, true));
			logger.info("旧对象：" + JSONObject.toJSONString(working, true));
		}
		return result;
	}
}
